﻿using CSCSN.EntitiyModels;
using CSCSN.ViewModels.RoleAndUser;
using CSCSN.ViewModelServices;
using CSCSN.ViewModelServices.Extensions;
using CSCSN.ViewModelServices.Tools;
using CSCSN.WebApplication.BaseControllers;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Reflection;
using System.Threading.Tasks;
using System.Timers;

namespace CSCSN.WebApplication.Controllers
{

    public class ApplicationUserController : BasePaginationTemplateController<ApplicationUser, ApplicationUserVM>
    {
        public IViewModelService<ApplicationUser, ApplicationUserVM> ss;
        public static bool Code;
        static string _email;                                                                   //电子邮箱全局变量
        static IDictionary<string, string> _emailAndCaptcha = new Dictionary<string, string>(); //实例化一个静态的字典对象,用于盛放邮箱账号与邮箱验证码
        static System.Timers.Timer t = new System.Timers.Timer(300000);                         //实例化Timer类，设置间隔时间为300000毫秒(5分钟);用于废弃验证码

        public ApplicationUserController(IViewModelService<ApplicationUser, ApplicationUserVM> service) : base(service)
        {
             ss = service;
        }
        public async Task<IActionResult> Create()
        {
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> Create(ApplicationUserVM boVM)
        {

            if (ModelState.IsValid && Code)
            {
                var bo = await ss.EntityRepository.ApplicationUserManager.FindByNameAsync(boVM.UserName);
                if (bo == null)
                {
                    bo = new ApplicationUser();
                    boVM.MapToEntityModel<ApplicationUserVM, ApplicationUser>(bo);//视图模型到实体模型的转换
                    var result = await ss.EntityRepository.ApplicationUserManager.CreateAsync(bo, boVM.Password);
                    if (result != IdentityResult.Success)
                    {
                        ModelState.AddModelError("UserName", "未知异常，注册失败，请重试");
                        return View(boVM);
                    }
                    var user = await ss.EntityRepository.ApplicationUserManager.FindByIdAsync(bo.Id.ToString());
                    var role = ss.EntityRepository.EntitiesContext.ApplicationRoles.Where(s => s.NormalizedName == "Student".ToUpper()).FirstOrDefault();
                    if (role == null)//种子文件数据库学生角色数据有误
                    {
                        await ss.EntityRepository.ApplicationUserManager.DeleteAsync(user);//删除已成功注册的账号
                        ModelState.AddModelError("UserName", "未知异常，注册失败，请重试");
                        return View(boVM);
                    }
                    IdentityResult IR = null;
                    IR = await ss.EntityRepository.ApplicationUserManager.AddToRoleAsync(user, "Student");//用户注册后，默认角色类型为Student
                    if (IR != IdentityResult.Success)//为用户赋予学生身份失败
                    {
                        await ss.EntityRepository.ApplicationUserManager.DeleteAsync(user);//删除已成功注册的账号
                        ModelState.AddModelError("UserName", "未知异常，注册失败，请重试");
                        return View(boVM);
                    }
                    return RedirectToAction("Creat", "PersonCentrel", new { ID = user.Id });//成功注册账号并赋给账号学生角色后，跳转新增个人信息页。
                }
                else
                {
                    ModelState.AddModelError("UserName", "邮箱已注册");
                }

            }
            return View(boVM); 


        }
        /// <summary>
        /// 实现向邮箱发送验证码
        /// </summary>
        /// <param name="email">邮箱</param>
        /// <returns>邮箱不存在，无提示；邮箱存在，返回“邮箱已被注册”提示</returns>
        public static string _verificationcode;
        public string Createrandom(int codelengh)
        {

            /// 生成随机数字字符串
            int rep = 0;
            string str = string.Empty;
            long num2 = DateTime.Now.Ticks + rep;
            rep++;
            Random random = new Random(((int)(((ulong)num2) & 0xffffffffL)) | ((int)(num2 >> rep)));
            for (int i = 0; i < codelengh; i++)
            {
                int num = random.Next();
                str = str + ((char)(0x30 + ((ushort)(num % 10)))).ToString();
            }
            return str;

        }
        /// <summary>
        /// 传入用户输入的邮箱地址
        /// </summary>
        /// <param name="EmailID"></param>
        public void Mailbox(string EmailID)
        {
            _email = EmailID;                                         //将传入的邮箱账号作为全局变量
           

            MailMessage mailMessage = new MailMessage();

            //发件人邮箱地址，方法重载不同，可以根据需求自行选择。
            mailMessage.From = new MailAddress("2636800985@qq.com");
            //收件人邮箱地址。
            mailMessage.To.Add(new MailAddress(EmailID));
            //邮件标题。
            mailMessage.Subject = "验证码";
            _verificationcode = Createrandom(6);
            //邮件内容。
            mailMessage.Body = "【大学生综合服务网】你的验证码是" + _verificationcode + "，请尽快完成信息验证，验证码5分钟内有效，如非本人操作请忽略此信息。";
            //实例化一个SmtpClient类。
            SmtpClient client = new SmtpClient();
            //在这里我使用的是qq邮箱，所以是smtp.qq.com，如果你使用的是126邮箱，那么就是smtp.126.com。
            client.Host = "smtp.qq.com";
            //使用安全加密连接。
            client.EnableSsl = true;
            //不和请求一块发送。
            client.UseDefaultCredentials = false;
            //验证发件人身份(发件人的邮箱，邮箱里的生成授权码);
            client.Credentials = new NetworkCredential("2636800985@qq.com", "sgovqhgwuvttdijh");
            //发送
            client.Send(mailMessage);

            if(_emailAndCaptcha.ContainsKey(EmailID) is false)                                //用户首次获取验证码
            {
                _emailAndCaptcha.Add(EmailID, _verificationcode);                              //新增用户与验证码
                t.Elapsed += new System.Timers.ElapsedEventHandler(SetCaptchaInvalid);        //到达时间的时候执行事件；
                t.AutoReset = false;                                                          //设置是执行一次（false）还是一直执行(true)；
                t.Enabled = true;                                                             //是否执行System.Timers.Timer.Elapsed事件；
                t.Start();                                                                    //启动定时器
            }

            else                                                                              //用户重新获取验证码
            {
                _emailAndCaptcha[EmailID] = _verificationcode;                                 //更新用户的验证码
                t.Enabled = false;                                                            //将之前未完成的废弃验证码事件取消
                t.Elapsed += new System.Timers.ElapsedEventHandler(SetCaptchaInvalid);        //到达时间的时候执行事件；
                t.AutoReset = false;                                                          //设置是执行一次（false）还是一直执行(true)；
                t.Enabled = true;                                                             //是否执行System.Timers.Timer.Elapsed事件；
                t.Start();                                                                    //启动定时器

            }
           
           
           
           
           
         
        }
        /// <summary>
        /// 验证码发送五分钟后，未用于注册，将验证码设为无效
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private static void SetCaptchaInvalid(object source, ElapsedEventArgs e)
        {
            _emailAndCaptcha[_email] = "Invalid";
        }


        /// <summary>
        /// 判断用户输入的验证码是否与生成的验证码一致
        /// 
        /// </summary>
        /// <param name="Verificat"></param>
        /// <returns></returns>
        public JsonResult JudgeVerificat(string verificat,string email)
        {
            Code = false;
            if (string.IsNullOrEmpty(verificat)||string.IsNullOrEmpty(email))//如果邮箱账号空值或者验证码空值
            {
                
                if (string.IsNullOrEmpty(verificat))
                    return Json("请输入验证码");
                else
                    return Json("请输入邮箱");
            }
            else
            {
                if (_emailAndCaptcha.ContainsKey(email) is true)             //判断键是否存在
                {
                    if (_emailAndCaptcha[email] == verificat)                //判断此账号的验证码是否正确
                    {
                        Code = true;
                        return Json("通过");
                    }
                   
                }
                    return Json("验证码错误");
            }
        }
        public ActionResult ForgetPassword()
        {
            return View();

        }
        [HttpPost]
        public async Task<IActionResult> ForgetPassword(ApplicationUserVM boVM)
        {

            var bo = new ApplicationUser();
            boVM.MapToEntityModel<ApplicationUserVM, ApplicationUser>(bo);//视图模型到实体模型的转换
            if (boVM.Captcha == _verificationcode && Code)
            {

                var result = await ss.EntityRepository.ApplicationUserManager.FindByNameAsync(boVM.UserName);//通过邮箱查找该用户
                if (result != null)
                {
                    string codepwd = await ss.EntityRepository.ApplicationUserManager.GeneratePasswordResetTokenAsync(result);//查询后生成登录令牌
                    var pwd = await ss.EntityRepository.ApplicationUserManager.ResetPasswordAsync(result, codepwd, boVM.Password);//修改密码
                    if (pwd.Succeeded)
                    {
                       // return RedirectToAction(nameof(ResetSuccess));
                        return RedirectToAction("ResetSuccess", "ApplicationUser");
                    }
                    return View(boVM);

                }
                else
                {
                    ModelState.AddModelError("", "邮箱不存在，请重新输入");
                    return View(boVM);
                }

            }
            else
            { return View(boVM); }


        }
        public IActionResult ResetSuccess()
        {
            return View();
        }
    }
}
